import { NzSafeAny } from "ng-zorro-antd/core/types";

export class BaseIdModel {
	id: string;

	constructor(o?: NzSafeAny) {
		this.id = o && o.id ? o.id : null;
	}
}

export class BaseVersionModel extends BaseIdModel {
	version: number;

	constructor(o?: NzSafeAny) {
		super(o);
		this.version = o && o.version ? o.version : null;
	}
}

export class BaseAuditModel extends BaseVersionModel {
	createdDate: Date | null;
	createdBy: string;
	lastModifiedDate: Date | null;
	lastModifiedBy: string;
	ranking: number

	constructor(o?: NzSafeAny) {
		super(o);
		this.createdDate = o && o.createdDate ? this.parseDate(o.createdDate) : null;
		this.createdBy = o && o.createdBy ? o.createdBy : null;
		this.lastModifiedDate = o && o.lastModifiedDate ? this.parseDate(o.lastModifiedDate) : null;
		this.lastModifiedBy = o && o.lastModifiedBy ? o.lastModifiedBy : null;
		this.ranking = o && o.ranking ? o.ranking : null;
	}

	parseDate(o: NzSafeAny): Date {
		return new Date(o);
	}
}

export class BaseDataStatusModel extends BaseAuditModel {
	status: number;
	reserved: boolean;

	constructor(o?: NzSafeAny) {
		super(o);
		this.status = o && o.status ? o.status : null;
		this.reserved = o && o.reserved ? o.reserved : false;
	}
}

export class Pagable {
	page: number;
	size: number;
	sorts: Sort[] = [];


	constructor(o?: NzSafeAny) {
		this.page = o && o.page ? o.page : 1;
		this.size = o && o.size ? o.size : 10;
		this.sorts = o && o.sorts ? o.sorts : [];

		this.sorts = this.sorts.map((e) => new Sort(e.property, e.direction));
	}

	public removeSort(property: string) {
		const index = this.sorts.findIndex(e => e.property == property);
		if (index < 0) {
			return;
		}

		this.sorts.splice(index, 1);
	}

	public addSort(property: string, asc?: boolean) {
		let sort = this.sorts.find(e => e.property == property);
		if (sort == null) {
			sort = new Sort(property);
			this.sorts.push(sort);
		}

		sort.setDirection(asc ? asc : true);
	}

	public incrPage(): void {
		this.page += 1;
	}
	/** 重新分页 */
	public reset(): void {
		this.page = 1;
	}

}

export class Sort {
	property: string;
	direction: 'asc' | 'desc' | string;


	constructor(property: string, direction?: string) {
		this.property = property;
		this.direction = direction ? direction : 'asc';
	}

	public setDirection(asc: boolean): void {
		this.direction = asc ? 'asc' : 'desc';
	}
}

Sort.prototype.toString = function sortToString() {
	return `${this.property},${this.direction}`;
};

export class Page<T> {
	last: boolean;
	totalPages: number;
	totalElements: number;
	number: number;
	size: number;
	first: boolean;
	numberOfElements: number;
	content: T[];

	constructor(o?: NzSafeAny, callback?: (e: NzSafeAny) => T) {
		this.last = o && o.last ? o.last : true;
		this.totalPages = o && o.totalPages ? o.totalPages : 0;
		this.totalElements = o && o.totalElements ? o.totalElements : 0;
		this.number = o && o.number ? o.number : 1;
		this.size = o && o.size ? o.size : 10;
		this.first = o && o.first ? o.first : false;
		this.numberOfElements = o && o.numberOfElements ? o.numberOfElements : 0;
		this.content = o && o.content ? o.content : [];
		if (callback) {
			this.content = this.content?.map((e) => callback(e));
		}
	}

}


export function merge(source: NzSafeAny, target: NzSafeAny) {
	if (source) {
		Object.assign(target, source);
	}
}